package org.broncho.ccs.util;

import static org.broncho.ccs.Task.FLAGE_OP_Y;
import static org.broncho.ccs.Task.CCS_PROPERTIES;

import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.Transparency;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Properties;

import javax.imageio.ImageIO;
import javax.imageio.stream.FileImageOutputStream;

import org.broncho.ccs.Task;

/**
 * 生成文件
 * 
 * @author ZhangXiao
 * @time 2013-8-20
 */
public class FileUtil {

	private static int BUFFER_SIZE = 1024 * 1024 * 10;
	private static int IMAGE_W_H = 480;
	private static String OUTPUT_DIR = System.getProperty("user.home");

	private static String IMAGE_TYPE = ".png";
	private static String FILE_TYPE = ".ini";

	private static String FILE_ROOT = "";
	private static String IMAGE_ROOT = "";

	static {
		File config = new File(System.getProperty("user.dir") + File.separator
				+ CCS_PROPERTIES);
		Properties p = new Properties();
		try {
			if (config.exists()) {
				System.out.println("Load Config " + CCS_PROPERTIES
						+ " File ...");
				p.load(new FileInputStream(config));
				BUFFER_SIZE = Integer.parseInt(p.getProperty("BUFFER_SIZE")) * 1024 * 1024;
				IMAGE_W_H = Integer.parseInt(p.getProperty("IMAGE_W_H"));
				String tempOutputDir = p.getProperty("OUTPUT_DIR");
				if (tempOutputDir != null && !tempOutputDir.equals("")) {
					OUTPUT_DIR = p.getProperty("OUTPUT_DIR");
				}
			} else {
				System.out.println("Load Default Constant Config ...");
			}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	static {
		FILE_ROOT = OUTPUT_DIR + File.separator + "ini";
		IMAGE_ROOT = OUTPUT_DIR + File.separator + "png";
		File ff = new File(FILE_ROOT);
		if (!ff.exists()) {
			ff.mkdirs();
		}
		File ig = new File(IMAGE_ROOT);
		if (!ig.exists()) {
			ig.mkdirs();
		}
	}

	/**
	 * 一次子任务写一次文件，多个子任务信息写入同一个文件
	 * 
	 * @param task
	 *            {@link org.broncho.ccs.Task}
	 */
	public static void createResultFile(Task task, byte[] bts) {
		File resultFile = new File(FILE_ROOT + File.separator + task.getRfile()
				+ FILE_TYPE);
		StringBuffer sb = new StringBuffer();
		if (!resultFile.exists()) {
			try {
				resultFile.createNewFile();
			} catch (IOException e1) {
				e1.printStackTrace();
				System.err.println("Create File "
						+ resultFile.getAbsolutePath() + " Failed");
			}
			sb.append("<start>\n");
			sb.append("\t<tasks>" + task.getEdge() + "</tasks>\n");
			sb.append("</start>\n");
		}
		sb.append("\n<task>\n\t<head>\n\t\t<provider>" + task.getProvider()
				+ "</provider>\n");
		sb.append("\t\t<subtask>[" + task.getStart() + "," + task.getEnd()
				+ ")<subtask>\n\t\t<taketime>" + task.getWastetime()
				+ "</taketime>\n\t</head>\n\t<result>\n");
		int edge = task.getEdge();
		for (int y = 0; y < edge; y++) {
			sb.append("\t[");
			for (int x = 0; x < edge; x++) {
				sb.append(bts[edge * y + x]);
				if (x != edge - 1) {
					sb.append(", ");
				} else {
					sb.append("]\n");
				}
			}
			if (sb.length() >= BUFFER_SIZE) {
				writeToFile(sb, resultFile);
				sb.setLength(0);
			}
		}
		sb.append("\t</result>\n</task>\n");
		writeToFile(sb, resultFile);
	}

	/**
	 * 将字符串写入文件
	 * 
	 * @param sb
	 *            内容字符串
	 * @param resultFile
	 *            目标文件
	 */
	private static void writeToFile(StringBuffer sb, final File resultFile) {
		FileWriter fwriter = null;
		try {
			fwriter = new FileWriter(resultFile, true);
			fwriter.write(sb.toString());
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				if (fwriter != null) {
					fwriter.close();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

	/**
	 * 创建图片文件
	 * 
	 * @param imageName
	 *            图片文件名
	 * @param bts
	 *            图片内容
	 * @param wh
	 *            图片宽和高的值
	 * @param edge
	 *            图片内容
	 * @param flag
	 *            图片内容标识
	 */
	private static void createImage(File imageName, byte[] bts, int wh,
			int edge, byte flag) {
		FileImageOutputStream fios = null;
		try {
			fios = new FileImageOutputStream(imageName);
		} catch (FileNotFoundException e) {
			e.printStackTrace();
			System.err.println("File Not Found!");
		} catch (IOException e) {
			e.printStackTrace();
			System.err.println("IO Exception!");
		}
		BufferedImage bimage = new BufferedImage(wh, wh,
				BufferedImage.TYPE_INT_RGB);
		Graphics2D g2d = bimage.createGraphics();
		g2d.getDeviceConfiguration().createCompatibleImage(wh, wh,
				Transparency.TRANSLUCENT);
		g2d.dispose();
		g2d = bimage.createGraphics();
		g2d.setBackground(Color.BLACK);

		// 这里计算不够精确，画面会出现干扰线
		int cellsize = wh / edge;

		for (int i = 0; i < edge; i++) {
			for (int j = 0; j < edge; j++) {
				Rectangle rect = new Rectangle(cellsize * j, cellsize * i,
						cellsize, cellsize);
				int index = i * edge + j;
				int length = bts.length;
				if (index < length && bts[index] == flag) {
					g2d.setColor(Color.RED);
					g2d.fill(rect);
					g2d.setColor(Color.WHITE);
					g2d.draw(rect);
				} else {
					g2d.setColor(Color.WHITE);
					g2d.draw(rect);
				}
			}
		}
		g2d.dispose();
		try {
			ImageIO.write(bimage, IMAGE_TYPE.substring(1), fios);
		} catch (IOException e) {
			e.printStackTrace();
			System.err.println("Write To Image File failed!");
		}
	}

	/**
	 * 生成一个子任务下存在的结果图片
	 * 
	 * @param task
	 *            {@link org.broncho.ccs.Task}
	 */
	public static void createResultImage(Task task, byte[] bts) {
		File parentDir = new File(IMAGE_ROOT + File.separator + task.getEdge());
		System.out.println(parentDir.getAbsolutePath());
		if (!parentDir.exists()) {
			parentDir.mkdirs();
		}
		File image = new File(parentDir.getAbsolutePath() + File.separator
				+ task.getImage() + IMAGE_TYPE);
		createImage(image, bts, IMAGE_W_H, task.getEdge(), FLAGE_OP_Y);
	}
}
